{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:41:04.785345Z",
     "start_time": "2020-06-17T06:41:03.910186Z"
    }
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 使用 CPU"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:41:06.647395Z",
     "start_time": "2020-06-17T06:41:06.614046Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "No GPU found\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU'),\n",
       " PhysicalDevice(name='/physical_device:XLA_CPU:0', device_type='XLA_CPU')]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "os.environ['CUDA_VISIBLE_DEVICES'] = '-1'\n",
    "\n",
    "if tf.test.gpu_device_name():\n",
    "    print('GPU found')\n",
    "else:\n",
    "    print(\"No GPU found\")\n",
    "\n",
    "my_devices = tf.config.experimental.list_physical_devices()\n",
    "my_devices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.gather"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.cast"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.reshape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.sequence_mask"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# tf.slice(input_, begin, size, name=None)\n",
    "beigin 为各个维度的起始索引点，size 为各个维度切片元素的 数量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-05-20T03:46:19.388116Z",
     "start_time": "2020-05-20T03:46:18.941497Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tf.Tensor(\n",
      "[[0 0 4 3]\n",
      " [0 0 1 3]\n",
      " [2 4 4 4]\n",
      " [2 0 3 3]], shape=(4, 4), dtype=int64)\n",
      "tf.Tensor(\n",
      "[[0 4 3]\n",
      " [0 1 3]\n",
      " [4 4 4]\n",
      " [0 3 3]], shape=(4, 3), dtype=int64)\n"
     ]
    }
   ],
   "source": [
    "a = tf.constant(np.random.randint(0, 5, size=(4, 4)))\n",
    "print(a)\n",
    "b = tf.slice(a, begin=[0, 1], size=[-1, 3])\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-05-20T06:41:17.153058Z",
     "start_time": "2020-05-20T06:41:17.149672Z"
    }
   },
   "source": [
    "# tf.cond(pred, true_fn=None, false_fn=None, name=None)\n",
    "pred 为真时，执行 true_fn() 函数，否则执行 false_fn() 函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-05-20T06:43:47.699424Z",
     "start_time": "2020-05-20T06:43:47.691954Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(2,), dtype=int32, numpy=array([6, 5], dtype=int32)>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = tf.constant([[1, 2, 3], [4, 1, 0]])\n",
    "\n",
    "\n",
    "def f1():\n",
    "    return x**2\n",
    "\n",
    "\n",
    "def f2():\n",
    "    return tf.reduce_sum(x, axis=-1)\n",
    "\n",
    "\n",
    "tf.cond(tf.shape(x)[-1] != 3, f1, f2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# tf.scan(fn,elems,**keargs)\n",
    "\n",
    "根据 `elems` 的第 0 维用 `fn`进行扫描；fn 接受两个参数，第一个参数为之前激活 fn 的累计值，第二个参数为 `elems` 的当前元素\n",
    "> 特定情况下，可以方便实现动态规划"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-05-20T07:03:32.330238Z",
     "start_time": "2020-05-20T07:03:32.212567Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(6,), dtype=int64, numpy=array([ 1,  3,  6, 10, 15, 21])>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "elems = np.array([1, 2, 3, 4, 5, 6])\n",
    "sum = tf.scan(lambda a, x: a + x, elems)\n",
    "sum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# tf.tile((input, multiples, name=None))\n",
    "将 input 的各个维度重复 multiples 上对应维度上数值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-13T01:59:27.650124Z",
     "start_time": "2020-06-13T01:59:27.633144Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(4, 6), dtype=int32, numpy=\n",
       "array([[1, 2, 3, 1, 2, 3],\n",
       "       [4, 1, 0, 4, 1, 0],\n",
       "       [1, 2, 3, 1, 2, 3],\n",
       "       [4, 1, 0, 4, 1, 0]], dtype=int32)>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = tf.constant([[1, 2, 3], [4, 1, 0]])\n",
    "tf.tile(x, [2, 2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-13T07:59:57.085026Z",
     "start_time": "2020-06-13T07:59:57.082435Z"
    }
   },
   "source": [
    "# tf.einsum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "转置:$B_{ji}=A_{ij}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:42:20.811321Z",
     "start_time": "2020-06-17T06:42:20.808007Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(2, 3), dtype=float32, numpy=\n",
       "array([[0.8758718 , 0.4365437 , 0.38201618],\n",
       "       [0.50707936, 0.5221009 , 0.5417745 ]], dtype=float32)>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = tf.random.uniform((2, 3))\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:42:27.841628Z",
     "start_time": "2020-06-17T06:42:27.838612Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(3, 2), dtype=float32, numpy=\n",
       "array([[0.8758718 , 0.50707936],\n",
       "       [0.4365437 , 0.5221009 ],\n",
       "       [0.38201618, 0.5417745 ]], dtype=float32)>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = tf.einsum(\"ij->ji\", a)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "求和：$b=\\sum\\limits_{i}\\sum\\limits_{j}A_{ij}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:44:53.316663Z",
     "start_time": "2020-06-17T06:44:53.313770Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(), dtype=float32, numpy=3.2653863>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = tf.einsum(\"ij->\", a)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:46:38.354908Z",
     "start_time": "2020-06-17T06:46:38.352394Z"
    }
   },
   "source": [
    "列求和：$b=\\sum\\limits_{i}A_{ij}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:46:56.535542Z",
     "start_time": "2020-06-17T06:46:56.532625Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(3,), dtype=float32, numpy=array([1.3829511, 0.9586446, 0.9237907], dtype=float32)>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = tf.einsum(\"ij->j\", a)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "矩阵乘法：$C_{ij} = \\sum\\limits_{k}A_{ik}B_{kj}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:51:48.224590Z",
     "start_time": "2020-06-17T06:51:48.220867Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(3, 4), dtype=float32, numpy=\n",
       "array([[-0.99365306,  0.24569835, -0.4555341 , -0.18225688],\n",
       "       [-1.1832956 , -1.9588448 , -2.2628129 , -0.65367246],\n",
       "       [-0.42967057,  0.86160624,  0.5546088 ,  0.45343527]],\n",
       "      dtype=float32)>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = tf.random.normal((3, 5))\n",
    "b = tf.random.uniform((5, 4))\n",
    "c = tf.einsum(\"ij,jk->ik\", a, b)\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:53:57.136282Z",
     "start_time": "2020-06-17T06:53:57.132418Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(), dtype=int32, numpy=23>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Dot product\n",
    "u = tf.constant([1, 2, 3])\n",
    "v = tf.constant([2, 3, 5])\n",
    "tf.einsum('i,i->', u, v)  # output = sum_i u[i]*v[i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:54:28.399495Z",
     "start_time": "2020-06-17T06:54:28.395442Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(3, 3), dtype=int32, numpy=\n",
       "array([[ 2,  3,  5],\n",
       "       [ 4,  6, 10],\n",
       "       [ 6,  9, 15]], dtype=int32)>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Outer product\n",
    "tf.einsum('i,j->ij', u, v)  # output[i,j] = u[i]*v[j]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:56:18.754286Z",
     "start_time": "2020-06-17T06:56:18.751276Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(), dtype=int32, numpy=5>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Trace\n",
    "m = tf.constant([[1, 2], [3, 4]])\n",
    "tf.einsum('ii', m)  # output[j,i] = trace(m) = sum_i m[i, i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-17T06:57:29.140113Z",
     "start_time": "2020-06-17T06:57:29.136046Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(2, 3, 7), dtype=float32, numpy=\n",
       "array([[[-0.04714242, -0.58901787,  1.827867  ,  1.7002294 ,\n",
       "          1.0728605 , -0.44502312, -0.7983513 ],\n",
       "        [ 1.7442985 ,  0.05938584,  1.2370716 , -0.5335729 ,\n",
       "          2.0766802 , -0.1455391 , -1.0797524 ],\n",
       "        [ 0.7962718 , -0.8501762 ,  1.8877522 ,  0.7560884 ,\n",
       "          1.1441047 ,  0.03892493, -0.98979926]],\n",
       "\n",
       "       [[ 0.7783072 , -1.4198673 , -0.76826286, -1.3987927 ,\n",
       "         -0.5849587 , -0.9192537 ,  1.018877  ],\n",
       "        [ 1.4122456 , -2.0655475 , -1.4665165 , -0.4460135 ,\n",
       "         -1.8070424 , -0.8549925 ,  0.23259544],\n",
       "        [ 1.4935722 , -3.0562093 , -0.5718592 ,  0.70153415,\n",
       "         -1.3151858 ,  0.08705962, -0.07307735]]], dtype=float32)>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Batch matrix multiplication\n",
    "s = tf.random.uniform((2, 3, 5))\n",
    "t = tf.random.normal((2, 5, 7))\n",
    "tf.einsum('aij,ajk->aik', s, t)  # out[a,i,k] = sum_j s[a,i,j] * t[a, j, k]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
